﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DoubanApiLib.Attributes;
using System.Data;
using System.Reflection;


namespace DoubanApiLib.EntityBase
{
    [Serializable]
    public class Entity<T> : IEntity<T> where T : new()
    {
        #region 操作

        /// <summary>
        /// 从DataSet中实例化对象第一个对象
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        public static T CreateInstance(DataSet ds)
        {

            T acc = new T();
            Type objType = acc.GetType();
            PropertyInfo[] propinfos = objType.GetProperties();
            ClassAttribute c_attr = (ClassAttribute)objType.GetCustomAttributes(typeof(ClassAttribute), false)[0];
            string ls_tablename = c_attr.TableName;
            string ls_ID_Tag = c_attr.TableName + "_Id";
            //所有实体的表
            DataTable lstTable = ds.Tables[ls_tablename];
            int index = 0;
            foreach (PropertyInfo item in propinfos)
            {
                string mode = "two"; //two 两个参数加载模式 four 四个参数加载模式
                if (item.GetCustomAttributes(false).Count() > 0)
                {
                    //反射特性
                    string TableName, RowName, Param1, Param2;
                    TableName = RowName = Param1 = Param2 = string.Empty;
                    PropertyAttribute attrs = item.GetCustomAttributes(false)[0] as PropertyAttribute;
                    if (attrs != null)
                    {
                        TableName = attrs.TableName;
                        RowName = attrs.RowName;
                        Param1 = attrs.Param1;
                        Param2 = attrs.Param2;
                        if (!string.IsNullOrEmpty(Param1) && !string.IsNullOrEmpty(Param2))
                        {
                            mode = "four";
                        }
                        DataTable dtMain = ds.Tables[TableName];

                        //判断属性数据加载模式
                        if (mode == "two")
                        {
                            acc.SetPropertyValue(item.Name, dtMain.Rows[index][RowName].ToString());
                        }
                        else
                        {
                            string data = lstTable.Rows[index][ls_ID_Tag].ToString();
                            //判断表中是否有标志
                            if (dtMain.Columns.Contains(ls_ID_Tag))
                            {
                                DataRow[] rows = dtMain.Select("{0}='{1}' and {2}='{3}'".FormatMe(ls_ID_Tag, data, Param1, Param2));

                                if (rows.Length >= 1)
                                {
                                    acc.SetPropertyValue(item.Name, rows[0][RowName]);
                                }
                            }
                        }
                    }
                }
            }

            return acc;
        }

        /// <summary>
        /// 从DataSet中实例化对象的集合
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        public static List<T> CreateInstanceList(DataSet ds)
        {
            List<T> lstData = new List<T>();

            Type objType = typeof(T);
            PropertyInfo[] propinfos = objType.GetProperties();
            ClassAttribute c_attr = (ClassAttribute)objType.GetCustomAttributes(typeof(ClassAttribute), false)[0];
            //数据表名
            string ls_tablename = c_attr.TableName;
            //主键列名
            string ls_ID_Tag = c_attr.TableName + "_Id";

            //数据表
            DataTable lstTable = ds.Tables[ls_tablename];

            int index = 0;
            foreach (DataRow mainRow in lstTable.Rows)
            {
                T acc = new T();
                foreach (PropertyInfo item in propinfos)
                {
                    string mode = "two"; //two 两个参数加载模式 four 四个参数加载模式
                    if (item.GetCustomAttributes(false).Count() > 0)
                    {
                        //反射特性
                        string TableName, RowName, Param1, Param2;

                        TableName = RowName = Param1 = Param2 = string.Empty;
                        PropertyAttribute attrs = item.GetCustomAttributes(false)[0] as PropertyAttribute;
                        if (attrs != null)
                        {
                            TableName = attrs.TableName;
                            RowName = attrs.RowName;
                            Param1 = attrs.Param1;
                            Param2 = attrs.Param2;
                            if (!string.IsNullOrEmpty(Param1) && !string.IsNullOrEmpty(Param2))
                            {
                                mode = "four";
                            }
                            DataTable dtMain = ds.Tables[TableName];
                            string data = mainRow[ls_ID_Tag].ToString();
                            //判断属性数据加载模式
                            if (mode == "two")
                            {
                                DataRow[] rows = dtMain.Select("{0}='{1}'".FormatMe(ls_ID_Tag, data));
                                if (rows.Length >= 1)
                                {
                                    acc.SetPropertyValue(item.Name, rows[0][RowName].ToString());
                                }
                            }
                            else
                            {

                                //判断表中是否有标志
                                if (dtMain.Columns.Contains(ls_ID_Tag))
                                {
                                    DataRow[] rows = dtMain.Select("{0}='{1}' and {2}='{3}'".FormatMe(ls_ID_Tag, data, Param1, Param2));

                                    if (rows.Length >= 1)
                                    {
                                        acc.SetPropertyValue(item.Name, rows[0][RowName]);
                                    }
                                }
                            }
                        }
                    }
                }

                lstData.Add(acc);
            }

            return lstData;

        }

        #endregion
    }
}
